package pkg.dao;

import com.googlecode.objectify.Key;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import pkg.entity.Auction;
import pkg.entity.Audit;
import pkg.entity.Bid;
import pkg.entity.Grade;
import pkg.entity.ObjectifyEntity;
import pkg.entity.Prefix;
import pkg.entity.Teacher;
import pkg.entity.User;

public class EntityDAO {

    static {
        ObjectifyService.register(Auction.class);
        ObjectifyService.register(Audit.class);
        ObjectifyService.register(Bid.class);
        ObjectifyService.register(Grade.class);
        ObjectifyService.register(Prefix.class);
        ObjectifyService.register(Teacher.class);
        ObjectifyService.register(User.class);
    }
    Objectify ofy;

    public EntityDAO() {
        ofy = ObjectifyService.begin();
    }

    public <T extends Serializable> T find(Class<T> objectClass, Long key) {
        return ofy.find(objectClass, key);
    }

    public <T extends Serializable> T find(Key<T> key) {
        return ofy.find(key);
    }

    public <T extends Serializable> List<T> findAll(Class<T> objectClass) {
        Query<T> query = ofy.query(objectClass);

        List<T> entities = new ArrayList<T>();
        for (T e : query) {
            entities.add(e);
        }
        return entities;
    }

    public Object findOneByFilter(Filter filter) {
        Object result = null;
        List l = findAllByFilter(filter);

        if (l.size() > 0) {
            result = l.get(0);
        }
        return result;
    }

    public List findAllByFilter(Filter filter) {
        return filter.getElements(ofy);
    }

    public PagedList findPagedListByFilter(Filter filter) {
        PagedList list = new PagedList();
        list.setResults(filter.getElements(ofy));
        return list;
    }

    public int getCountByFilter(Filter filter) {
        return filter.getCount(ofy);
    }

    public <T> T internalUpdate(T updatableObject) {
        ofy.put(updatableObject);
        return updatableObject;
    }

    public <T extends Serializable> T update(T updatableObject) {
        return internalUpdate(updatableObject);
    }

    public void delete(Object deletableObject) {
        Key pk = ((ObjectifyEntity) deletableObject).getPrimaryKey();
        if (pk != null) {
            ofy.delete(pk);
        }
    }

    public <T extends Serializable> void delete(List<Key> keys) {
        for (Key key : keys) {
            ofy.delete(keys);
        }
    }

    public <T extends Serializable> void delete(Class<T> objectClass, List<Long> ids) {
        List<Key> keys = new ArrayList<Key>();
        for (long id : ids) {
            keys.add(new Key(objectClass, id));
        }
        delete(keys);
    }

}
